package com.neiquan.backstage.weixin.web.action;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.neiquan.backstage.platform_alliance_member.PlatformAllianceMemberService;
import com.neiquan.backstage.platform_weixin.handler.DefaultHandler;
import com.neiquan.backstage.platform_weixin.handler.SubscribeHandler;
import com.neiquan.backstage.platform_weixin.handler.UnsubscribeHandler;
import com.neiquan.backstage.pub.bsc.dao.po.PlatformAllianceMember;

import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;

@Controller
@RequestMapping(value = "weixin", produces = { "text/json;charset=UTF-8" })
public class WeixinAction {
	private static final Logger log = LoggerFactory.getLogger(WeixinAction.class);
	@Autowired
	private PlatformAllianceMemberService platformAllianceMemberService;
	@ResponseBody
	@RequestMapping("recvMsgOrEvent")
	public String recvMsgOrEvent(HttpServletRequest req, Integer memberId) throws IOException {
		log.debug("recvMsgOrEvent, method={}", req.getMethod());

		String signature = req.getParameter("signature");
		String nonce = req.getParameter("nonce");
		String timestamp = req.getParameter("timestamp");
		WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage = new WxMpInMemoryConfigStorage();
		PlatformAllianceMember platformAllianceMember = platformAllianceMemberService.queryById(memberId);
		wxMpInMemoryConfigStorage.setAppId(platformAllianceMember.getWeixinAppId());
		wxMpInMemoryConfigStorage.setSecret(platformAllianceMember.getWeixinAppSecret());
		wxMpInMemoryConfigStorage.setToken(platformAllianceMember.getWeixinToken());
		wxMpInMemoryConfigStorage.setAesKey(platformAllianceMember.getWeixinEncodingAesKey());
		WxMpService wxMpService = new WxMpServiceImpl();
		wxMpService.setWxMpConfigStorage(wxMpInMemoryConfigStorage);
		WxMpMessageRouter wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
		wxMpMessageRouter //
				.rule().async(false).event(WxConsts.EVT_SUBSCRIBE).handler(new SubscribeHandler()).end() //
				.rule().async(false).event(WxConsts.EVT_UNSUBSCRIBE).handler(new UnsubscribeHandler()).end() //
				.rule().async(false).handler(new DefaultHandler()).end();
		if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
			// 消息签名不正确，说明不是公众平台发过来的消息
			log.debug("非法请求");
			return "非法请求";
		}

		String echostr = req.getParameter("echostr");
		if (StringUtils.isNotBlank(echostr)) {
			log.debug("echostr {}", echostr);
			// 说明是一个仅仅用来验证的请求，回显echostr
			return echostr;
		}

		String encryptType = StringUtils.isBlank(req.getParameter("encrypt_type")) ? "raw" : req.getParameter("encrypt_type");

		if ("raw".equals(encryptType)) {
			// 明文传输的消息
			WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(req.getInputStream());
			log.debug("raw inMessage={}", inMessage.toString());
			WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
			return outMessage.toXml();
		}

		if ("aes".equals(encryptType)) {
			// 是aes加密的消息
			String msgSignature = req.getParameter("msg_signature");
			WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(req.getInputStream(), wxMpInMemoryConfigStorage, timestamp, nonce, msgSignature);
			log.debug("aes inMessage={}", inMessage.toString());
			WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
			return outMessage.toEncryptedXml(wxMpInMemoryConfigStorage);
		}

		log.debug("不可识别的加密类型");
		return "不可识别的加密类型";
	}
}
